package com.education.admin.modules.miniprogram.service.impl;

import com.education.admin.common.Result;
import com.education.admin.modules.miniprogram.service.MiniInviteService;
import com.education.admin.modules.student.mapper.StudentMapper;
import com.education.admin.modules.miniprogram.mapper.UserInviteCodeMapper;
import com.education.admin.modules.miniprogram.mapper.InvitationRecordMapper;
import com.education.admin.modules.student.entity.Student;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Slf4j
@Service
@RequiredArgsConstructor
public class MiniInviteServiceImpl implements MiniInviteService {

    private final StudentMapper studentMapper;
    private final UserInviteCodeMapper inviteCodeMapper;
    private final InvitationRecordMapper invitationRecordMapper;

    @Override
    public Result<Map<String, Object>> generateStudentInviteCode() {
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            String phone = request.getHeader("X-User-Phone");
            Student s = (phone==null||phone.isEmpty()) ? null : studentMapper.findByPhone(phone);
            if (s == null) return Result.error("学生信息获取失败");
            // 查询是否已生成
            Map<String,Object> exist = inviteCodeMapper.findByUser(s.getId(), "student", "invite");
            String code;
            if (exist != null && exist.get("code") != null) {
                code = String.valueOf(exist.get("code"));
            } else {
                code = generateCodeFromId(s.getId());
                inviteCodeMapper.insert(s.getId(), "student", "invite", code);
            }
            Map<String,Object> data = new HashMap<>();
            data.put("inviteCode", code);
            data.put("studentId", s.getId());
            data.put("studentName", s.getStudentName());
            return Result.success(data);
        }catch(Exception e){
            log.error("生成邀请码失败", e);
            return Result.error("生成邀请码失败");
        }
    }

    @Override
    public Result<Map<String, Object>> generateStudentBindCode() {
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            String phone = request.getHeader("X-User-Phone");
            Student s = (phone==null||phone.isEmpty()) ? null : studentMapper.findByPhone(phone);
            if (s == null) return Result.error("学生信息获取失败");
            Map<String,Object> exist = inviteCodeMapper.findByUser(s.getId(), "student", "bind");
            String code;
            if (exist != null && exist.get("code") != null) {
                code = String.valueOf(exist.get("code"));
            } else {
                code = generateCodeFromId(s.getId()+10000); // 区分生成
                inviteCodeMapper.insert(s.getId(), "student", "bind", code);
            }
            Map<String,Object> data = new HashMap<>();
            data.put("bindCode", code);
            data.put("studentId", s.getId());
            data.put("studentName", s.getStudentName());
            return Result.success(data);
        }catch(Exception e){
            log.error("生成绑定码失败", e);
            return Result.error("生成绑定码失败");
        }
    }

    @Override
    public Result<String> acceptInviteCode(String code) {
        try{
            if(code==null || code.trim().isEmpty()) return Result.error("邀请码不能为空");
            code = code.trim().toUpperCase();
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            String phone = request.getHeader("X-User-Phone");
            Student me = (phone==null||phone.isEmpty()) ? null : studentMapper.findByPhone(phone);
            if (me == null) return Result.error("学生信息获取失败");
            Map<String,Object> myInvite = inviteCodeMapper.findByUser(me.getId(), "student", "invite");
            if (myInvite!=null && code.equalsIgnoreCase(String.valueOf(myInvite.get("code")))){
                return Result.error("不能填写自己的邀请码");
            }
            Map<String,Object> target = inviteCodeMapper.findByCode(code);
            if (target==null) return Result.error("无效邀请码");
            Long inviterId = ((Number)target.get("userId")).longValue();
            if (invitationRecordMapper.exists(inviterId, me.getId())==0) {
                invitationRecordMapper.insert(null, inviterId, "student", me.getId(), "student", code);
            }
            return Result.success("接受成功");
        }catch(Exception e){
            log.error("接受邀请码失败", e);
            return Result.error("提交失败");
        }
    }

    @Override
    public Result<java.util.List<java.util.Map<String, Object>>> listInvited() {
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            String phone = request.getHeader("X-User-Phone");
            Student me = (phone==null||phone.isEmpty()) ? null : studentMapper.findByPhone(phone);
            if (me == null) return Result.error("学生信息获取失败");
            return Result.success(invitationRecordMapper.listInvitees(me.getId()));
        }catch(Exception e){
            log.error("获取邀请列表失败", e);
            return Result.error("获取邀请列表失败");
        }
    }

    private String generateCodeFromId(Long id){
        String base = Long.toString((id==null?0:id) * 1315423911L, 36).toUpperCase();
        String pad = randomPad(2);
        return (base + pad).substring(0, Math.min(8, base.length()+pad.length()));
    }

    private String randomPad(int n){
        String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
        Random r = new Random(); StringBuilder sb = new StringBuilder();
        for(int i=0;i<n;i++){ sb.append(chars.charAt(r.nextInt(chars.length()))); }
        return sb.toString();
    }
}


